# -*- coding: utf-8 -*-

from flask_sqlalchemy import SQLAlchemy
from server import app
from app.enum.stock import ListStatusEnum, IsHsEnum, BoolIntEnum
import datetime

db = SQLAlchemy(app)


class BaseModel(db.Model):
    __abstract__ = True

    @classmethod
    def update_or_create(cls, attributes, values):
        instance = cls.query.filter_by(**attributes).first()
        if not instance:
            instance = cls(**attributes)
        for key, value in values.items():
            if hasattr(instance, key):
                setattr(instance, key, value)
        return instance


class Stock(BaseModel):
    __tablename__ = 'stocks'
    __table_args__ = {'comment': '股票表'}
    id = db.Column(db.Integer, primary_key=True)
    ts_code = db.Column(db.CHAR(10), unique=True, nullable=False, default='', comment='TS代码')
    symbol = db.Column(db.CHAR(6), unique=True, nullable=False, default='', comment='股票代码')
    name = db.Column(db.CHAR(12), index=True, nullable=False, default='', comment='股票名称')
    area = db.Column(db.CHAR(16), nullable=False, default='', comment='所在地域')
    industry = db.Column(db.String(255), nullable=False, default='', comment='所属行业')
    fullname = db.Column(db.String(255), nullable=False, default='', comment='股票全称')
    enname = db.Column(db.String(255), nullable=False, default='', comment='英文全称')
    market = db.Column(db.String(64), nullable=False, default='', comment='市场类型 （主板/中小板/创业板/科创板/CDR）')
    exchange = db.Column(db.String(10), nullable=False, default='', comment='交易所代码')
    curr_type = db.Column(db.CHAR(3), nullable=False, default='', comment='交易货币')
    list_status = db.Column(db.CHAR(3), nullable=False, default=ListStatusEnum.LIST, comment='上市状态： L上市 D退市 P暂停上市')
    list_date = db.Column(db.CHAR(8), nullable=False, default='', comment='上市日期')
    delist_date = db.Column(db.CHAR(8), nullable=True, default=None, comment='退市日期')
    is_hs = db.Column(db.CHAR(3), nullable=False, default=IsHsEnum.NO, comment='是否沪深港通标的，N否 H沪股通 S深股通')
    create_at = db.Column(db.DateTime, default=datetime.datetime.now, comment='创建时间')
    update_at = db.Column(db.DateTime, default=datetime.datetime.now, onupdate=datetime.datetime.now, comment='更新时间')


class Index(BaseModel):
    __tablename__ = 'indexes'
    __table_args__ = {'comment': '指数表'}
    id = db.Column(db.Integer, primary_key=True)
    ts_code = db.Column(db.CHAR(32), unique=True, nullable=False, default='', comment='TS代码')
    name = db.Column(db.String(64), index=True, nullable=False, default='', comment='简称')
    fullname = db.Column(db.String(255), nullable=False, default='', comment='指数全称')
    market = db.Column(db.CHAR(10), nullable=False, default='', comment='市场')
    publisher = db.Column(db.String(64), nullable=False, default='', comment='发布方')
    index_type = db.Column(db.String(64), nullable=False, default='', comment='指数风格')
    category = db.Column(db.String(64), nullable=False, default='', comment='指数类别')
    base_date = db.Column(db.CHAR(10), nullable=False, default='', comment='基期')
    base_point = db.Column(db.DECIMAL(10, 2), nullable=False, default=0.00, comment='基点')
    list_date = db.Column(db.CHAR(10), nullable=False, default='', comment='发布日期')
    weight_rule = db.Column(db.String(64), nullable=False, default='', comment='加权方式')
    # desc = db.Column(db.String(255), nullable=False, default='', comment='描述')
    exp_date = db.Column(db.CHAR(10), nullable=False, default='', comment='终止日期')
    create_at = db.Column(db.DateTime, default=datetime.datetime.now, comment='创建时间')
    update_at = db.Column(db.DateTime, default=datetime.datetime.now, onupdate=datetime.datetime.now, comment='更新时间')


class TradeCalendar(BaseModel):
    __tablename__ = 'trade_calendars'
    __table_args__ = (db.Index('ix_trade_calendars_exchange_cal_date', 'exchange', 'cal_date'), {'comment': '交易日历表'})
    id = db.Column(db.Integer, primary_key=True)
    exchange = db.Column(db.CHAR(6), nullable=False, default='', comment='交易所')
    cal_date = db.Column(db.CHAR(10), nullable=False, default='', comment='日历日期')
    is_open = db.Column(db.SMALLINT, nullable=False, default=BoolIntEnum.FALSE, comment='是否交易 0休市 1交易')
    pretrade_date = db.Column(db.CHAR(10), index=True, nullable=False, default='', comment='上一个交易日')
    create_at = db.Column(db.DateTime, default=datetime.datetime.now, comment='创建时间')
    update_at = db.Column(db.DateTime, default=datetime.datetime.now, onupdate=datetime.datetime.now, comment='更新时间')


class StockName(BaseModel):
    __tablename__ = 'stock_names'
    __table_args__ = (
        db.Index('ix_stock_names_ts_code_start_date', 'ts_code', 'start_date'), {'comment': '股票曾用名表'})
    id = db.Column(db.Integer, primary_key=True)
    ts_code = db.Column(db.CHAR(10), nullable=False, default='', comment='TS代码')
    name = db.Column(db.CHAR(12), index=True, nullable=False, default='', comment='股票名称')
    start_date = db.Column(db.CHAR(10), nullable=False, default='', comment='开始日期')
    end_date = db.Column(db.CHAR(10), nullable=False, default='', comment='结束日期')
    ann_date = db.Column(db.CHAR(10), nullable=False, default='', comment='公告日期')
    change_reason = db.Column(db.VARCHAR(255), nullable=False, default='', comment='变更原因')
    create_at = db.Column(db.DateTime, default=datetime.datetime.now, comment='创建时间')
    update_at = db.Column(db.DateTime, default=datetime.datetime.now, onupdate=datetime.datetime.now, comment='更新时间')


class StockIncome(BaseModel):
    __tablename__ = 'stock_incomes'
    __table_args__ = ({'comment': '股票利润表'})
    id = db.Column(db.Integer, primary_key=True)
    ts_code = db.Column(db.CHAR(10), index=True, nullable=False, default='', comment='TS代码')
    ann_date = db.Column(db.CHAR(10), nullable=False, default='', comment='公告日期')
    f_ann_date = db.Column(db.CHAR(10), nullable=False, default='', comment='实际公告日期')
    end_date = db.Column(db.CHAR(10), index=True, nullable=False, default='', comment='报告期')
    report_type = db.Column(db.SMALLINT, nullable=False, default=0, comment='报告类型')
    comp_type = db.Column(db.SMALLINT, nullable=False, default=0, comment='公司类型(1一般工商业2银行3保险4证券)')
    total_revenue = db.Column(db.DECIMAL(18, 4), nullable=False, default=0.0000, comment='营业总收入')
    revenue = db.Column(db.DECIMAL(18, 4), nullable=False, default=0.0000, comment='营业收入')
    total_cogs = db.Column(db.DECIMAL(18, 4), nullable=False, default=0.0000, comment='营业总成本')
    oper_cost = db.Column(db.DECIMAL(18, 4), nullable=False, default=0.0000, comment='减:营业成本')
    operate_profit = db.Column(db.DECIMAL(18, 4), nullable=False, default=0.0000, comment='营业利润')
    total_profit = db.Column(db.DECIMAL(18, 4), nullable=False, default=0.0000, comment='利润总额')
    n_income = db.Column(db.DECIMAL(18, 4), nullable=False, default=0.0000, comment='净利润(含少数股东损益)')
    update_flag = db.Column(db.SMALLINT, nullable=False, default=0, comment='报告类型')
    create_at = db.Column(db.DateTime, default=datetime.datetime.now, comment='创建时间')
    update_at = db.Column(db.DateTime, default=datetime.datetime.now, onupdate=datetime.datetime.now, comment='更新时间')
